package com.netty.demo.application.netty;

import com.netty.demo.domain.model.Message;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class NettyServerHandler extends SimpleChannelInboundHandler {
    //初始化channels，用来统一操作所有连接到服务器的客户端channels列表。
    private static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    @Override
    public boolean acceptInboundMessage(Object msg) throws Exception {
        log.info("服务器收到消息了!");
        return super.acceptInboundMessage(msg);
    }
    
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //貌似是传入msg类型如果不是指定类型，会重新触发channelRead，直到获取到所需的类型(这里是Message)
        log.info("开始读来自" + ctx.channel().remoteAddress() + "消息喽!");
        super.channelRead(ctx, msg);
        // ByteBuf buf = (ByteBuf) msg;
        // buf.writeBytes(buf); // (2)
        // buf.release();
    }

    /*@Override
    protected void channelRead0(ChannelHandlerContext ctx, Message message) throws Exception {
        for (Channel channel : channels) {
            log.info("remoteAddress = {}", channel.remoteAddress());
            channel.writeAndFlush(message);
        }
        System.out.print("[" + message.getUsername() + "]:" + message.getMessage());
    }*/
    
    @Override
    protected void messageReceived(ChannelHandlerContext channelHandlerContext, Object o) throws Exception {

    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        log.info("Execute:channelRegistered");
        super.channelRegistered(ctx);
    }

    /*@Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        // log.info("Execute:channelUnregistered");
        // super.channelUnregistered(ctx);
        // ctx.close();
    }*/

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel incoming = ctx.channel();
        log.info("Client:" + incoming.remoteAddress() + "在线");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        log.info("服务器处理完这次消息喽!");
        super.channelReadComplete(ctx);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        log.info("Execute:userEventTriggered");
        super.userEventTriggered(ctx, evt);
    }

    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
        log.info("Execute:channelWritabilityChanged");
        super.channelWritabilityChanged(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.info("Execute:exceptionCaught");
        Channel incoming = ctx.channel();
        log.info("Client:" + incoming.remoteAddress() + "异常");
        cause.printStackTrace();
        log.info("isRemoved = {}", ctx.isRemoved());
        ctx.close();
        log.info("isRemoved = {}", ctx.isRemoved());
        channels.remove(incoming);
        log.info("channels.size() = {}", channels.size());
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel incoming = ctx.channel();
        log.info("Client:" + incoming.remoteAddress() + "连接成功");
        channels.add(incoming);
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {

    }
}
